#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @author: Florian Dorn <florian.dorn@gmail.com>
# @package: agenda
# @license: GNU GPLv2
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

import gobject
import gtk
import gtk.gdk

import dateutil
import dateutil.rrule
import datetime

from gettext import gettext as _

from agenda import DAY_FMT, TIME_FMT

"""
This is an edit field for iCal Event/Todo time(s)

it contains  the following controls:
* start datetime (can be null in TODO mode)
* end datetime   (can be null in TODO mode)
* recurrencerule-set
  http://labix.org/python-dateutil#head-f83f4f0dd5fa533e0260bdcdd08df927594c32d2
"""

DAY_TIME_FMT = "%s\n%s" % (DAY_FMT, TIME_FMT)

class iCalTimeEdit(gtk.Alignment):
	MODE_EVENT = 0
	MODE_TODO  = 1

	RRULE_NONE = -1
	RRULE_DAILY = dateutil.rrule.DAILY
	RRULE_WEEKLY = dateutil.rrule.WEEKLY
	RRULE_MONTHLY = dateutil.rrule.MONTHLY
	RRULE_YEARLY = dateutil.rrule.YEARLY

	_attributes = {  }
	def reset(self):

		rruleset = None
		mode = iCalTimeEdit.MODE_EVENT
		all_day = False
		start = self.__cleanup_datetime(datetime.datetime.now())
		if start.time().minute < 29:
			start = start.replace(minute=30)
		else:
			start = start.replace(minute=0) + datetime.timedelta(seconds=3600)

		end = start + datetime.timedelta(seconds=3600)

		self._attributes = {'start': start, 'end': end, 'rruleset': rruleset,'mode': mode,'all_day' : all_day}


		self.format = DAY_TIME_FMT
		
		self.set_start(start)
		self.set_end(end)
		
		self.set_all_day(all_day)
		self.rruleset_combo.set_active(0)
		
	def __init__(self,start = None, end = None):
		gtk.Alignment.__init__(self,0,0.5,0,1.0)
		#the widgets
		vbox = gtk.VBox()
		
		self.button = gtk.Button(None)
		self.button.set_relief(gtk.RELIEF_NONE)
		hbox = gtk.HBox(False,5)
		
		self.label_start = gtk.Label()
		self.label_start.set_justify(gtk.JUSTIFY_CENTER)

		self.label_end = gtk.Label()
		self.label_end.set_justify(gtk.JUSTIFY_CENTER)

		self.label_until = gtk.Label()
		self.label_until.set_text(_("until"))

		hbox.pack_start(self.label_start)
		hbox.pack_start(self.label_until)
		hbox.pack_start(self.label_end)

		self.button.add(hbox)

		vbox.pack_start(self.button)

		rruleset_model_store = gtk.ListStore(int,str)
		rruleset_model_store.append( [iCalTimeEdit.RRULE_NONE,_('Does not repeat') ] )
		rruleset_model_store.append( [iCalTimeEdit.RRULE_DAILY,_('Daily') ] )
		rruleset_model_store.append( [iCalTimeEdit.RRULE_WEEKLY,_('Weekly') ] )
		rruleset_model_store.append( [iCalTimeEdit.RRULE_MONTHLY,_('Monthly') ] )
		rruleset_model_store.append( [iCalTimeEdit.RRULE_YEARLY,_('Yearly') ] )

		self.rruleset_combo = gtk.ComboBox(rruleset_model_store)
		cell = gtk.CellRendererText()
		self.rruleset_combo.pack_start(cell, True)
		self.rruleset_combo.add_attribute(cell, 'text', 1)
		self.rruleset_combo.connect('changed',self.on_rrulseset_combo_change)
		self.rruleset_combo.set_active(0)
		
		alignment = gtk.Alignment(0,0.5,0,1.0)
		alignment.add( self.rruleset_combo )
		vbox.pack_start(alignment)

		self.add(vbox)
		self.show_all()

		self.reset()

		
	def __updatelabels(self):
		self.label_start.set_label(self._attributes['start'].strftime(self.format))
		self.label_end.set_label(self._attributes['end'].strftime(self.format))

	def __cleanup_datetime(self,datetime):
		return datetime.replace(second = 0, microsecond = 0)


	def on_rrulseset_combo_change(self,combobox):
		model = combobox.get_model()
		active = combobox.get_active()
		rrule_type = model[active][0]
		#print (model[active][0],model[active][1])
		self.update_rruleset( rrule_type )
		

	def update_rruleset(self,rrule_type):
		rrset = dateutil.rrule.rruleset()
		if rrule_type == iCalTimeEdit.RRULE_NONE:
			self.set_rruleset(rrset)
		else:
			rrset.rrule(dateutil.rrule.rrule(rrule_type,dtstart=self.get_start()))
		self.set_rruleset(rrset)
		#print rrset
	"""
	Set the start datetime
	"""
	def set_start(self,start):
		start = self.__cleanup_datetime(start)
		if (start > self._attributes['end']):
			print "new start is after end"
			old_end = self._attributes['end']
			self.set_end(start)
			self.set_start(old_end)
		else:
			self._attributes['start'] = start
	
		self.__updatelabels()
	"""
	get the start datetime
	"""
	def get_start(self):
		return self._attributes['start']
	"""
	set the end date time
	"""
	def set_end(self,end):
		self._attributes['end'] = self.__cleanup_datetime(end)
		if (end < self._attributes['start']):
			print "new end is before start"
			old_start = self._attributes['start']
			self.set_start(end)
			self.set_end(old_start)

		else:
			self._attributes['end'] = end
		self.__updatelabels()
	"""
	get the end date time
	"""
	def get_end(self):
		return self._attributes['end']
	"""
	set the mode
	
	possible values are iCalTimeEdit.MODE_EVENT iCalTimeEdit.MODE_TODO
	"""
	def set_mode(self,mode):
		self._attributes['mode'] = mode
	"""
	return true if the duration represents "All day"
	"""
	def get_all_day(self):
		return self._attributes['all_day']
	def set_all_day(self,all_day = True):
		self._attributes['all_day'] = all_day
		if all_day:
			self.format = DAY_FMT
		else:
			self.format = DAY_TIME_FMT
		self.__updatelabels()
	"""
	return the recurrence rule
	"""
	def get_rruleset(self):
		return self._attributes['rruleset']
	def set_rruleset(self,rruleset):
		self._attributes['rruleset'] = rruleset
		#now = datetime.datetime.now()
		#for date in rruleset.between(now,now + datetime.timedelta(39)):
		#	print date

	def do_get_property(self, pspec):
		if pspec.name in self._attributes:
			return self._attributes[pspec.name]

	def do_set_property(self, pspec, value):
		if pspec.name == 'start':
			self.set_start(value)
		elif pspec.name == 'end':
			self.set_end(end)
		elif pspec.name == 'rruleset':
			self.set_rruleset(value)
		elif pspec.name == 'mode':
			self.set_rruleset(value)

	def get_widget(self):
		return self.button
